package de.sordul.md5crack.impl.optimizedMultiCore;

import java.math.BigInteger;
import java.util.List;

import de.sordul.md5crack.CrackGUI;

/**
 * Checks how many hashes had been computed already and displays the value within the GUI.
 */
public class StateChecker implements Runnable {

	private List<CrackWorker> crackWorkers;
	private BigInteger computedHashesSum = BigInteger.valueOf(0l);
	private long startTime;
	private double secondsResult;
	private boolean running;
	
	public StateChecker(List<CrackWorker> crackWorkers) {
		this.crackWorkers = crackWorkers;
		this.running = true;
	}
	
	@Override
	public void run() {
		
		// Avoid zero on fast machines
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		// Check periodically the number of computed hashes and display it
		startTime = System.nanoTime();
		do {
			for(CrackWorker worker: crackWorkers) {
				computedHashesSum = computedHashesSum.add( worker.getComputedHashes() );
			}
			
			CrackGUI.setComputedHashes(computedHashesSum);
			updateTime();
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			
			
		} while(CrackGUI.getResult() == null && running == true);		
	}

	/**
	 * Build an elapsed time string.
	 */
	private void updateTime() {
		
		// Build result in seconds
		secondsResult = System.nanoTime() - startTime;
		secondsResult = secondsResult/1000000000;
		int iSecondsResult = (int) Math.round(secondsResult);
		
		// Build minutes
		int minuteResult = 0;
		if(iSecondsResult/60 > 1) {
			minuteResult = (int) Math.round(iSecondsResult/60);
			iSecondsResult = iSecondsResult % 60;
		}
		 // Build hours
		int hourResult = 0;
		if(minuteResult != 0 && minuteResult/60 > 1) {
			hourResult = (int) Math.round(minuteResult/60);
			minuteResult = minuteResult % 60;			
		}
		
		// Show the string
		if(hourResult > 0) {
			CrackGUI.setLblElapsedTime(hourResult+"h "+minuteResult+"m "+iSecondsResult+"s");
		} else if(minuteResult > 0) {
			CrackGUI.setLblElapsedTime(minuteResult+"m "+iSecondsResult+"s");
		} else {
			CrackGUI.setLblElapsedTime(iSecondsResult+"s");
		}	
	}

	public void stop() {
		running = false;
	}

}
